<!DOCTYPE html>
<html>
<head>
<title>Optical Grating Diagram</title>
<style>
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        background-color: #f0f0f0;
    }
    canvas {
        border: 1px solid #ccc;
        background-color: #fff;
    }
</style>
</head>
<body>
<canvas id="physicsCanvas" width="600" height="450"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // --- Style and Font Settings ---
    // Use a font that mimics the handwritten style of the original diagram.
    const handwrittenFont = '22px "Comic Sans MS", cursive, sans-serif';
    const figureFont = 'bold 24px "Times New Roman", serif';

    // --- Helper Function to Draw Arrows ---
    function drawArrow(fromx, fromy, tox, toy) {
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.stroke();

        const headlen = 10;
        const angle = Math.atan2(toy - fromy, tox - fromx);
        ctx.beginPath();
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }

    // --- Geometric Parameters ---
    const gratingBaseY = 320;
    const gratingBodyHeight = 50;
    const toothHeight = 30;
    const toothWidth = 60;
    const numTeeth = 6;
    const gratingStartX = (canvas.width - numTeeth * toothWidth) / 2; // Center the grating horizontally
    const gratingEndX = gratingStartX + numTeeth * toothWidth;
    const gratingTopY = gratingBaseY - gratingBodyHeight; // Y-coord of the flat top part of the grating body

    // Calculate blaze angle α from geometry. tan(α) = opposite/adjacent = toothHeight/toothWidth
    const blazeAngleRad = Math.atan(toothHeight / toothWidth);
    // From the diagram and problem context (Littrow configuration), the incident angle θ is equal to the blaze angle α.
    const thetaRad = blazeAngleRad;

    // --- 1. Draw the Grating ---
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 2.5;

    // a. Draw the outline of the grating
    ctx.beginPath();
    ctx.moveTo(gratingStartX, gratingBaseY);
    ctx.lineTo(gratingEndX, gratingBaseY);
    ctx.lineTo(gratingEndX, gratingTopY);

    // b. Draw the sawtooth (echelette) surface
    for (let i = 0; i < numTeeth; i++) {
        const currentX = gratingEndX - i * toothWidth;
        const peakY = gratingTopY - toothHeight;
        ctx.lineTo(currentX, peakY); // Line to the peak
        ctx.lineTo(currentX - toothWidth, gratingTopY); // Line to the next valley
    }
    ctx.lineTo(gratingStartX, gratingTopY); // Connect back to the left side
    ctx.closePath();
    ctx.stroke();

    // c. Fill with hatching lines
    ctx.save();
    ctx.clip(); // Use the path above as a clipping region
    ctx.lineWidth = 1.5;
    const hatchSpacing = 15;
    for (let i = -canvas.height; i < canvas.width; i += hatchSpacing) {
        ctx.beginPath();
        ctx.moveTo(i, 0);
        ctx.lineTo(i + canvas.height + gratingBodyHeight, canvas.height);
        ctx.stroke();
    }
    ctx.restore();
    ctx.lineWidth = 2.5; // Reset line width

    // --- 2. Draw Incident Light, Normal, and Angles ---
    
    // a. Define a reference peak for drawing the normal and main angle
    const refPeakX = gratingEndX - 2 * toothWidth;
    const refPeakY = gratingTopY - toothHeight;

    // b. Draw the "normal to the grating" line (dashed)
    ctx.beginPath();
    ctx.setLineDash([6, 4]);
    ctx.moveTo(refPeakX, refPeakY);
    ctx.lineTo(refPeakX, 90);
    ctx.stroke();
    ctx.setLineDash([]); // Reset to solid lines

    // c. Draw the incident light rays
    const rayLength = 170;
    // The main ray for angle measurement hits the reference peak
    const mainRay_startX = refPeakX - rayLength * Math.sin(thetaRad);
    const mainRay_startY = refPeakY - rayLength * Math.cos(thetaRad);
    drawArrow(mainRay_startX, mainRay_startY, refPeakX, refPeakY);

    // Draw two other parallel rays hitting adjacent peaks for consistency
    const parallelOffset = toothWidth;
    drawArrow(mainRay_startX - parallelOffset, mainRay_startY, refPeakX - parallelOffset, refPeakY);
    drawArrow(mainRay_startX - 2 * parallelOffset, mainRay_startY, refPeakX - 2 * parallelOffset, refPeakY);

    // d. Draw the angle θ arc
    const arcRadiusTheta = 35;
    ctx.beginPath();
    ctx.arc(refPeakX, refPeakY, arcRadiusTheta, -Math.PI / 2, -Math.PI / 2 + thetaRad, false);
    ctx.stroke();

    // e. Draw the angle α arc inside a sawtooth triangle
    // We'll use the triangle to the left of the reference peak.
    const alphaCornerX = refPeakX - toothWidth;
    const alphaCornerY = gratingTopY;
    const arcRadiusAlpha = 25;
    ctx.beginPath();
    // Arc between the horizontal line (angle PI) and the slanted line (angle PI - blazeAngleRad)
    ctx.arc(alphaCornerX, alphaCornerY, arcRadiusAlpha, Math.PI, Math.PI - blazeAngleRad, true);
    ctx.stroke();

    // --- 3. Add All Text Labels ---
    ctx.fillStyle = 'black';

    // a. Main labels
    ctx.font = handwrittenFont;
    ctx.textAlign = 'left';
    ctx.fillText('incident light', 120, 70);
    ctx.fillText('normal to the grating', refPeakX + 15, 95);

    // b. Angle labels
    ctx.textAlign = 'center';
    ctx.fillText('θ = α', refPeakX + 58, refPeakY - 15);
    // Position alpha label inside its arc
    const alphaLabelX = alphaCornerX - arcRadiusAlpha * 0.7;
    const alphaLabelY = alphaCornerY - arcRadiusAlpha * 0.4;
    ctx.fillText('α', alphaLabelX, alphaLabelY);

    // c. Figure caption
    ctx.font = figureFont;
    ctx.fillText('Fig. 2.59', canvas.width / 2, canvas.height - 30);

</script>
</body>
</html>